<?php

namespace App\Command\ResumeParsing\Service;

use App\Command\ResumeParsing\Service as Service;
use App\Command\ResumeParsing\Service\ParsingSpecial as ParsingSpecial;

use EchoPHP\Facades\Log;

//读简历文件类
class ParsingHelper {
    private $resumeText;
    private $readFile;
    public $resumeInfo;
    private $fileType;
    private $parsingSpecial = false;
    private $autoFix = false;
    public $func;
    public $resume;
    public $debugSpecial = false;

    /**
     * @var ParsingSpecial\ParsingSpecial[]
     */
    public $specialParsers;

    function __construct() {
        $this->func = new Service\ParsingFunction();
        $this->autoFix = config('app.resume_machine_learning.fix_machinelearning_result');
        $this->specialParsers = array(
            1 => new ParsingSpecial\ParsingLiepin($this),        // /sample/1_猎聘自行下载吴昊一.doc                      已经完成
            2 => new ParsingSpecial\ParsingLiepin2($this),       // /sample/2_猎聘供应商下载图片需处理.docx                已经完成
            3 => new ParsingSpecial\ParsingZhilian($this),       // /sample/3_卓聘_智联曲红强.docx   3_卓聘_陈玉亮.docx    已经完成
            4 => new ParsingSpecial\ParsingLagou($this),         // /sample/4_拉钩_王文静.doc                             已经完成
            5 => new ParsingSpecial\Parsing51job($this),         // /sample/5_前程无忧_黄斐飏.doc                         已经完成
            6 => new ParsingSpecial\ParsingBoss($this),          // /sample/6_BOSS直聘_陈志伟.docx                        已经完成
            //7 => new ParsingSpecial\ParsingLagouPdf($this),      // /sample/7_拉勾招聘.pdf                                待开发  暂不处理
            //8 => new ParsingSpecial\ParsingLagou2($this),        // /sample/8_拉勾招聘_郭茂业_微软原生.doc                 待开发  暂不处理
            9 => new ParsingSpecial\Parsing51jobExcel($this),    // /sample/9_51jobExcel.doc                              已经完成
            10 => new ParsingSpecial\ParsingZhilian2($this),     // /sample/10_智联招聘_杜文斌_中文.doc                    已经完成
            11 => new ParsingSpecial\ParsingZhilianExcel($this), // /sample/11_智联金领简历1-100.xls                      已经完成
            12 => new ParsingSpecial\ParsingCustomExcel($this),  // /sample/12_非标准简历（手工录入用）.xlsx（工作表保护密码：rpo）已经完成
            20 => new ParsingSpecial\ParsingMachineLearning($this),  // 通过机器学习算法解析                               已经完成
        );
    }

    function getResume($resumeData, $autoTry = false) {

        /*
        $tmpStr = "期望地点:长春-人民广场，工资：期望城市:北京天安门，工资：";
        $exceptPreg = '/(期望城市|期望地点)(.*)(场|门)?/';
        preg_match($exceptPreg, $tmpStr, $matchesResult);
        var_dump($matchesResult);
        exit();
        */

        try {
            $this->fileType = $resumeData['fileSource'];

            if (empty($resumeData) || count($resumeData) < 1) {
                return array();
            }
            $this->resume = $resumeData;

            $this->parsingSpecial = false;
            if (isset($this->specialParsers[$this->fileType]) && $this->specialParsers[$this->fileType] instanceof ParsingSpecial\ParsingSpecial) {
                $parser = $this->specialParsers[$this->fileType];
                if ($parser instanceof ParsingSpecial\ParsingSpecialXml) {
                    if (!empty($this->resume['resumeDom']) && $parser->parse($this->resume['resumeDom'])) {
                        $this->parsingSpecial = $parser;
                    }
                } elseif ($parser instanceof ParsingSpecial\ParsingSpecialExcel) {
                    if (!empty($this->resume['resumeSheet']) && $parser->parse($this->resume['resumeSheet'])) {
                        $this->parsingSpecial = $parser;
                    }
                } else {
                    if (!empty($this->resume) && $parser->parse($this->resume)) {
                        $this->parsingSpecial = $parser;
                    }
                }
            }
            if (!$this->parsingSpecial && $autoTry) {
                foreach ($this->specialParsers as $i => $parser) {
                    if ($i == $this->fileType) continue;
                    if ($parser instanceof ParsingSpecial\ParsingSpecialXml) {
                        if (!empty($this->resume['resumeDom']) && $parser->parse($this->resume['resumeDom'])) {
                            $this->fileType = $i;
                            $this->parsingSpecial = $parser;
                            break;
                        }
                    } elseif ($parser instanceof ParsingSpecial\ParsingSpecialExcel) {
                        if (!empty($this->resume['resumeSheet']) && $parser->parse($this->resume['resumeSheet'])) {
                            $this->fileType = $i;
                            $this->parsingSpecial = $parser;
                            break;
                        }
                    } else {
                        if (!empty($this->resume) && $parser->parse($this->resume)) {
                            $this->fileType = $i;
                            $this->parsingSpecial = $parser;
                            break;
                        }
                    }
                }
            }

            if (!$this->parsingSpecial) {
                Log::error('调用简历解析方案失败', ['filePath' => $resumeData['filepath']], 'cmd');
                return false;
            }   //尝试所有解析方案后全部失败

            $this->parsingSpecial->debug = $this->debugSpecial;
            $resumeInfo = $this->func->resumeInit();

            $this->resumeInfo = &$resumeInfo;

            $resumeAtom = $this->func->aloneChar16($resumeData['resumeAtom']);
            $this->resumeText = $resumeAtom2 = $this->func->replaceChar16($resumeAtom);

            $this->getID();
            $this->getTime();
            $this->getSex();
            $this->getNation();
            $this->getIdentityCard();


            $this->getMobile();
            $this->getEmail();
            $this->getAge();
            $this->getMarried();
            $this->getPolitic();
            $this->getDegree();
            $this->getIndustry();
            $this->getPosition();
            $this->getCareer();

            $this->getMajor();

            $this->getName();
            $this->getBirthday();
            $this->getWorkyear();
            $this->getWorkArea();
            $this->getArea();
            $this->getExpectArea();

            $this->getSalary();
            $this->getExpectSalary();


            $this->getSchool();
            $this->getNoFocus();
            $this->getJobTerm();
            $this->getCurrentSituation();
            $this->getEntryTime();

            $this->getSource();


            $this->getWorkInfo();
            $this->getProjectInfo();
            $this->getEducationInfo();
            $this->getSkillInfo();
            $this->getAwardInfo();
            $this->getCommentInfo();
            $this->getOtherInfo();
            $this->getAvatar();

            $resumeSection = $this->func->aloneChar16($resumeData['resumeSection']);
            $resumeSection2 = $this->func->replaceChar16($resumeSection);

            $this->func->delPResume($resumeInfo);

            $resumeInfo['time'] = $this->func->parseTimespan($resumeInfo['time'])['begin'];
            $resumeInfo['birthday'] = $this->func->parseTimespan($resumeInfo['birthday'])['begin'];
            $resumeInfo['age'] = $this->func->preg_get('/(?<=^|\s)\d+(?=\s*岁?$)/u', $resumeInfo['age'], '岁');

            if ($resumeInfo['birthday'] == '0001-01-01' && !empty($resumeInfo['age']) && ($resumeInfo['age'] >= 18 && $resumeInfo['age'] <= 70)) {
                $time = time();
                if ($resumeInfo['time'] != '0001-01-01' && $tmp = @strtotime($resumeInfo['time'])) {
                    $time = $tmp;
                }
                $resumeInfo['birthday'] = (date('Y', $time) - $resumeInfo['age']) . '-01-01';
            }

            foreach (['name', 'mobile', 'email', 'sex'] as $field) {
                $resumeInfo[$field] = trim($resumeInfo[$field], "* \t\n\r\0\x0B");
                //手机号模型识别错误时容错处理
                if ($this->autoFix) {
                    if ($field == 'mobile' && is_numeric($resumeInfo[$field])) {
                        $resumeInfo[$field] = substr($resumeInfo[$field],0,11);
                    }
                    //性别模型识别错误时容错处理
                    if ($field == 'sex' && !empty($resumeInfo[$field])) {
                        if (preg_match('/男/',$resumeInfo[$field])) {
                            $resumeInfo[$field] = '男';
                        }
                        if (preg_match('/女/',$resumeInfo[$field])) {
                            $resumeInfo[$field] = '女';
                        }
                    }
                }
            }

            foreach (['skillinfo', 'awardinfo', 'otherinfo'] as $field) {
                $resumeInfo[$field] = preg_replace('/\s*\|\s*/u', ' | ', $resumeInfo[$field]);
            }

            $this->func->normalizeArrayFormat($resumeInfo['workinfo'], array('time' => '', 'time_from' => '', 'time_end' => '', 'company' => '', 'industry' => '', 'industry_code' => '', 'duty' => '', 'salary' => '', 'comment' => ''));
            $this->func->normalizeArrayFormat($resumeInfo['projectinfo'], array('time' => '', 'time_from' => '', 'time_end' => '', 'project' => '', 'company' => '', 'duty' => '', 'comment' => ''));
            $this->func->normalizeArrayFormat($resumeInfo['educationinfo'], array('time' => '', 'time_from' => '', 'time_end' => '', 'school' => '', 'major' => '', 'degree' => '', 'comment' => ''));

            $this->func->normalizeDelimiter($resumeInfo);
            if (is_array($resumeInfo['workinfo']) && count($resumeInfo['workinfo'])) {
                if (empty($resumeInfo['salaryfrom'])) {
                    $resumeInfo['salary'] = $resumeInfo['workinfo'][0]['salary'];
                    $salary = $this->func->parseSalary($resumeInfo['salary']);
                    if (count($salary)) {
                        $resumeInfo['salaryfrom'] = $salary['monthly']['begin'];
                        $resumeInfo['salaryend'] = $salary['monthly']['end'];
                    }
                }

                if (empty($resumeInfo['expectsalaryfrom']) && !empty($resumeInfo['salaryfrom'])) {
                    $resumeInfo['expectsalary'] = $resumeInfo['salary'];
                    $resumeInfo['expectsalaryfrom'] = $resumeInfo['salaryfrom'];
                    $resumeInfo['expectsalaryend'] = $resumeInfo['salaryend'];
                }
                if (empty($resumeInfo['industry']) || in_array($resumeInfo['industry'], ['其他', '其它'])) $resumeInfo['industry'] = $resumeInfo['workinfo'][0]['industry'];   //如果没指定期望行业，用最近工作行业代替
                if ((empty($resumeInfo['position']) || in_array($resumeInfo['position'], ['其他', '其它'])) && (empty($resumeInfo['career']) || in_array($resumeInfo['career'], ['其他', '其它']))) $resumeInfo['position'] = $resumeInfo['workinfo'][0]['duty'];   //如果没指定期望职位/职业，期望职位用最近工作职位代替
                $resumeInfo['company'] = $resumeInfo['workinfo'][0]['company'];   //最近工作职位
            }
            if (is_array($resumeInfo['educationinfo']) && count($resumeInfo['educationinfo'])) {
                if (empty($resumeInfo['school'])) $resumeInfo['school'] = $resumeInfo['educationinfo'][0]['school'];
                if (empty($resumeInfo['major'])) $resumeInfo['major'] = $resumeInfo['educationinfo'][0]['major'];
                if (empty($resumeInfo['degree'])) $resumeInfo['degree'] = $resumeInfo['educationinfo'][0]['degree'];
                foreach ($resumeInfo['educationinfo'] as &$item) {
                    if (!empty($item['comment'])) $item['comment'] = preg_replace('/^.{0,5}描述(?:\s*\pP+\s*|\s+)/u', '', $item['comment']);
                }
            }
            $this->getProfile();

            $resumeData['resumeInfo'] = $resumeInfo;
            //$this->func->printResume($resumeInfo);
            //var_dump($resumeInfo);
            return $resumeData;
        } catch (\Exception $e) {
            Log::error(e_dump($e), ['taskid' => $resumeData['taskid'], 'type' => $this->fileType], 'cmd');
            if ($this->debugSpecial) throw $e;
            return false;
        }
    }

    //简历来源
    function getSource() {
        $this->resumeInfo['source'] = $this->fileType;
        return;
    }

    //简历编号
    function getID() {
        if ($this->trySpecial('id')) return;

        $tagArr = array("简历编号信息", "简历编号", "简历id", "id");
        $this->getTag('id', $tagArr, '\S+', 0, TRUE);
    }

    //简历时间
    function getTime() {
        if ($this->trySpecial('time')) return;

        $tagArr = array("简历更新时间", "更新时间", "简历时间", "最后登录", "最后登录时间", "最后编辑", "最后编辑时间");
        $this->getTag('time', $tagArr,
            '(?:\d{2})?\d{2}(?:(?<year>年)|(?<delimiter>[\-\.\/\\\\]))[01]?\d(?(year)月|\k<delimiter>)[0-3]?\d(?(year)[日号])(?:\s*[012]?\d(?:(?<hour>[时点])|:)[0-5]?\d(?(hour)分|:)[0-5]?\d(?(hour)秒))?');
    }

    //性别  sexCode
    function getSex() {
        if ($this->trySpecial('sex')) return;

        $this->getTag('sex', '性别', '(?<result>[男女])性?', 2);
    }

    //民族  nationCode
    function getNation() {
        if ($this->trySpecial('nation')) return;

        //标准格式，要求有空格辅助
        if ($this->getTag('nation', '民族', '[\x{4e00}-\x{9fff}]{1,4}\s+族', 0, TRUE)) return;
        //无空格辅助，使用字典，必须有[民族]在前，可省略后面的“族”
        if ($this->getTag('nation', '民族', '(?:蒙古|维吾尔|布依|朝鲜|土家|哈尼|哈萨克|傈僳|拉祜|东乡|纳西|景颇|' .
            '柯尔克孜|达斡尔|仫佬|布朗|撒拉|毛南|仡佬|锡伯|阿昌|普米|塔吉克|乌兹别克|俄罗斯|鄂温克|德昂|保安|' .
            '裕固|塔塔尔|独龙|鄂伦春|赫哲|门巴|珞巴|基诺|高山|[汉回藏苗彝壮满侗瑶白傣黎佤畲水土羌怒京])\s+族?')) return;
        //无空格辅助，使用字典，[民族]可省略，不可省略后面的“族”
        $this->getTag('nation', '民族', '(?:蒙古|维吾尔|布依|朝鲜|土家|哈尼|哈萨克|傈僳|拉祜|东乡|纳西|景颇|' .
            '柯尔克孜|达斡尔|仫佬|布朗|撒拉|毛南|仡佬|锡伯|阿昌|普米|塔吉克|乌兹别克|俄罗斯|鄂温克|德昂|保安|' .
            '裕固|塔塔尔|独龙|鄂伦春|赫哲|门巴|珞巴|基诺|高山|[汉回藏苗彝壮满侗瑶白傣黎佤畲水土羌怒京])\s+族', 2);
    }

    //身份证  identityCardCode
    function getIdentityCard() {
        if ($this->trySpecial('identitycard')) return;

        $tagArr = array("身份证编号", "身份证号码", "身份证");
        $this->getTag('identitycard', $tagArr, '[1-9]\d{5}(?:18|19|(?:[23]\d))\d{2}(?:(?:0[1-9])|(?:10|11|12))(?:(?:[0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]' . //第二代
            '|[1-9]\d{5}\d{2}(?:(?:0[1-9])|(?:10|11|12))(?:(?:[0-2][1-9])|10|20|30|31)\d{3}', 2);    //第一代
    }

    //手机   手机国号
    function getMobile() {
        if ($this->trySpecial('mobile')) {
            return;
        }

        $tagArr = array("手机", "手机号码", "移动电话");
        if ($this->getTag('mobile', $tagArr, '(?:\+?\d{1,3}(?:[\s\-]\d{1,3})?[\s\-]*)?(?:\d\s?){5,11}')) return;    //兼容国际手机号
        $this->getTag('mobile', $tagArr, '(?:\+?86[\s\-]*)?(?:13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\s?\d{4}\s?\d{4}', 2);    //国内手机号
    }

    //邮箱
    function getEmail() {
        if ($this->trySpecial('email')) return;

        $tagArr = array("邮箱", "信箱", "邮件", "电子邮箱", "电子信箱", "电子邮件", "e\-mail(?:邮箱|信箱)?");
        if ($this->getTag('email', $tagArr, '\S+@[\w\-]+\.\S+')) return;
        $this->getTag('email', $tagArr, '\S+@[\w\-]+\.\S+', 2);
    }

    //年龄
    function getAge() {
        if ($this->trySpecial('age')) return;

        $tagArr = array("年龄", "年纪");
        if ($this->getTag('age', $tagArr, '\d{2}(?:\s*岁)?')) return;
        $this->getTag('age', $tagArr, '\d{2}\s{0,2}岁', 2);
    }

    //姓名
    function getName() {
        if ($this->trySpecial('name')) return;

        static $regexFamilyNames = '(?:万俟|司马|上官|欧阳|夏侯|诸葛|闻人|东方|赫连|皇甫|尉迟|公羊|澹台|公冶|宗政|濮阳|淳于|单于|太叔|申屠|公孙|仲孙|轩辕|令狐|锺离|宇文|' .
            '长孙|慕容|鲜于|闾丘|司徒|司空|丌官|司寇|子车|颛孙|端木|巫马|公西|漆雕|乐正|壤驷|公良|拓拔|夹谷|宰父|谷梁|段干|百里|东郭|南门|呼延|羊舌|' .
            '微生|梁丘|左丘|东门|西门|南宫|[赵钱孙李周吴郑王冯陈楮卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎' .
            '鲁韦昌马苗凤花方俞任袁柳酆鲍史唐费廉岑薛雷贺倪汤滕殷罗毕郝邬安常乐于时傅皮卞齐康伍余元卜顾孟平黄和穆萧尹姚邵湛汪祁毛禹狄米贝明臧' .
            '计伏成戴谈宋茅庞熊纪舒屈项祝董梁杜阮蓝闽席季麻强贾路娄危江童颜郭梅盛林刁锺徐丘骆高夏蔡田樊胡凌霍虞万支柯昝管卢莫经房裘缪干解应宗' .
            '丁宣贲邓郁单杭洪包诸左石崔吉钮龚程嵇邢滑裴陆荣翁荀羊於惠甄麹家封芮羿储靳汲邴糜松井段富巫乌焦巴弓牧隗山谷车侯宓蓬全郗班仰秋仲伊宫' .
            '宁仇栾暴甘斜厉戎祖武符刘景詹束龙叶幸司韶郜黎蓟薄印宿白怀蒲邰从鄂索咸籍赖卓蔺屠蒙池乔阴鬱胥能苍双闻莘党翟谭贡劳逄姬申扶堵冉宰郦雍' .
            '郤璩桑桂濮牛寿通边扈燕冀郏浦尚农温别庄晏柴瞿阎充慕连茹习宦艾鱼容向古易慎戈廖庾终暨居衡步都耿满弘匡国文寇广禄阙东欧殳沃利蔚越夔隆' .
            '师巩厍聂晁勾敖融冷訾辛阚那简饶空曾毋沙乜养鞠须丰巢关蒯相查后荆红游竺权逑盖益桓公晋楚阎法汝鄢涂钦仉督归海岳帅缑亢况後有琴商牟佘佴' .
            '伯赏墨哈谯笪年爱阳佟第五言福肖操覃来芦])';

        $tagArr = array("姓名", "名称");
        if ($this->getTag('name', $tagArr, '[\x{4e00}-\x{9fff}]{2,4}', 0, TRUE)) return;
        if ($this->getTag('name', $tagArr, $regexFamilyNames . '[\x{4e00}-\x{9fff}]{2}', 2)) return;
        if ($this->getTag('name', $tagArr, $regexFamilyNames . '[\x{4e00}-\x{9fff}]', 2)) return;
        $this->getTag('name', $tagArr, $regexFamilyNames . '[\x{4e00}-\x{9fff}]{3}', 2);
    }

    //生日
    function getBirthday() {
        if ($this->trySpecial('birthday')) return;

        $tagArr = array("生日", "出生日期", "出生年月", "出生年月日");
        if ($this->getTag('birthday', $tagArr, '(?:\d{2})?\d{2}年[01]?\d月(?:[0-3]?\d[日号])?|(?:\d{2})?\d{2}(?<delimiter>[\-\.\/\\\\])[01]?\d(?:\k<delimiter>[0-3]?\d)?')) return;
        $this->getTag('birthday', $tagArr, '\d{2}\s{0,2}岁\s*[\pP\pS]?(?<result>(?:\d{2})?\d{2}年[01]?\d月(?:[0-3]?\d[日号])?|(?:\d{2})?\d{2}(?<delimiter>[\-\.\/\\\\])[01]?\d(?:\k<delimiter>[0-3]?\d)?)[\pP\pS]?', 2);
    }

    //工作年限  workyearCode
    function getWorkyear() {
        if ($this->trySpecial('workyear')) return;

        $tagArr = array("工作年限", "工作经验", "工龄");
        $this->getTag('workyear', $tagArr, '(?<!\d)(?:\d{1,2}年(?:\s{0,2}[01]?\d个?月)?|\d{1,2}个?月)(?:以上|\+)?', 1);
    }

    //目前工作地  workAreaCode
    function getWorkArea() {
        if ($this->trySpecial('workarea')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("所在地", "所在城市", "工作地址", "工作地区", "城市", "现居住地", "居住地", "现居地");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen($doTxtArr[$j]) <= 10) {
                    $resumeInfo['workarea'] = $doTxtArr[$j];
                    $resumeInfo['workarea_p'] = $j;
                }
                return;
            }
        }

        for ($i = 0; $i < $num; $i++) {
            if (mb_strlen($doTxtArr[$i]) > 200) {
                //break;
            }
            $tmpStr = str_replace(array(":", "："), '', $doTxtArr[$i]);
            $exceptPreg = '/(?:(?:所在地|所在城市|工作地址|工作地区|城市|现居住地|居住地|现居地)\s*)(\S*)(?=市|区|\b|\s)/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);

            if (isset($matchesResult[1]) && $matchesResult[1] != "" && mb_strlen(trim($matchesResult[1])) < 20) {
                $resumeInfo['workarea'] = trim(trim($matchesResult[1]), '|');
                $resumeInfo['workarea_p'] = $i;
                return;

                $dictCityArr = $functionObj->dictCity();
                foreach ($dictCityArr as $key => $value) {
                    if (strpos($matchesResult[1], $value) !== false) {
                        $resumeInfo['workarea'] = $value;
                        $resumeInfo['workarea_p'] = $i;
                        return;
                    }
                }
            }
        }
        return;
    }

    //户口所在地  areaCode
    function getArea() {
        if ($this->trySpecial('area')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("户口城市", "户口地址", "户口所在地", "户籍城市", "户籍地址", "户籍所在地区",
                "户籍所在地", "户籍国籍", "户口国籍", "国籍", "户籍", "籍贯", "户口");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen($doTxtArr[$j]) <= 10) {
                    $resumeInfo['area'] = $doTxtArr[$j];
                    $resumeInfo['area_p'] = $j;
                }
                return;
            }
        }
        for ($i = 0; $i < $num; $i++) {
            if (mb_strlen($doTxtArr[$i]) > 200) {
                break;
            }
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $exceptPreg = '/(?:(?:户口城市|户口地址|户口所在地|户籍城市|户籍地址|户籍所在地区|户籍所在地|国籍|户籍|籍贯|户口))(\S*)(?:市|区|\b|\s)/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);

            if (isset($matchesResult[1]) && $matchesResult[1] != "" && mb_strlen($matchesResult[1]) < 50) {
                $resumeInfo['area'] = $matchesResult[1];
                $resumeInfo['area_p'] = $i;
                return;

                $dictCityArr = $functionObj->dictCity();
                foreach ($dictCityArr as $key => $value) {
                    if (strpos($matchesResult[1], $value) !== false) {
                        $resumeInfo['area'] = $value;
                        $resumeInfo['area_p'] = $i;
                        return;
                    }
                }
            }
        }
        return;
    }

    //期望工作地  expectAreaCode
    function getExpectArea() {
        if ($this->trySpecial('expectarea')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("期望工作地区", "期望工作地", "期望工作城市", "期望城市", "期望地点");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen($doTxtArr[$j]) <= 10) {
                    $resumeInfo['expectarea'] = $doTxtArr[$j];
                    $resumeInfo['expect_p'] = $j;
                }
                return;
            }
        }
        for ($i = 0; $i < $num; $i++) {
            if (mb_strlen($doTxtArr[$i]) > 100) {
                break;
            }
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);

            //$exceptPreg = '/期望地点(.*)?/';
            $exceptPreg = '/(?:(?:期望工作城市|期望城市|期望地点|期望工作地区|期望工作地)\s*)(.+)(?:省|市|区|\b|\s)/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);
            if (isset($matchesResult[1]) && $matchesResult[1] != "" && mb_strlen($matchesResult[1]) < 20) {
                $resumeInfo['expectarea'] = $matchesResult[1];
                $resumeInfo['expect_p'] = $i;
                return;
            }
        }
        return;
    }

    //目前薪资  salaryCode
    function getSalary() {
        if ($this->trySpecial('salary')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $tagArr = array("工作年限", "工作经验", "工龄");
        $this->getTag('salary', '(?<!期望|预期)(?:年薪|月薪|薪资|年收入)', '\d{1,2}年(?:[01]?\d个?月)?(?:以上|\+)?', 1);
        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("目前薪资", "目前年薪", "年薪", "薪资", "目前年收入");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen($doTxtArr[$j]) <= 10) {
                    $resumeInfo['salary'] = $doTxtArr[$j];
                    $resumeInfo['salary_p'] = $j;
                }
                return;
            }
        }
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = str_replace(array("：", ":"), '', $doTxtArr[$i]);
            //$exceptPreg = '/(?:(?<!期望|预期)(?:年薪|月薪|薪资|年收入)\s*)(\d{1,10}(?:|k|K|w|W|万|万)元?)\b/u';
            $exceptPreg = '/(?:(?<!期望|预期)(?:年薪|薪资|年收入)\s*)(.*(?:|k|K|w|W|万|万)元?)\b\s/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);
            if (isset($matchesResult[1]) && $matchesResult[1] != "") {
                $resumeInfo['salary'] = $matchesResult[1];
                $resumeInfo['salary_p'] = $i;
                return;
            }
        }
        return;
    }

    //期望薪资开始  expectSalary
    function getExpectSalary() {
        if ($this->trySpecial('expectsalary')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("期望薪资", "期望年薪", "期望工资", "期望月薪");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                for ($m = $j; $m < $j + 6; $m++) {
                    if (strpos($doTxtArr[$m], "万") > 1 || strpos($doTxtArr[$m], "元") > 1 && mb_strlen(trim(trim($doTxtArr[$m], '|'))) <= 200) {
                        $resumeInfo['expectsalary'] = trim(trim($doTxtArr[$m], '|'));
                        $resumeInfo['expectsalary_p'] = $m;
                        return;
                    }
                }
            }
        }
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = str_replace(array("：", ":"), '', $doTxtArr[$i]);
            $exceptPreg = '/(?:(?:期望|预期)(?:年薪|薪资|月薪)\s*)(\S*(?:|k|K|w|W|万)元?)\b\s/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);
            if (isset($matchesResult[1]) && $matchesResult[1] != "") {
                $resumeInfo['expectsalary'] = $matchesResult[1];
                $resumeInfo['expectsalary_p'] = $i;
                return;
            }

            $exceptPreg = '/(?:(?:期望|预期)(?:年薪|薪资|月薪)：?:?\s*)(面议)\b/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);
            if (isset($matchesResult[1]) && $matchesResult[1] != "") {
                $resumeInfo['expectsalary'] = $matchesResult[1];
                $resumeInfo['expectsalary_p'] = $i;
                return;
            }
        }
        return;
    }

    //期望薪资开始  expectSalaryFromCode
    function getExpectSalaryFrom() {
        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));
        return;
    }

    //期望薪资结束  expectSalaryEndCode
    function getExpectSalaryEnd() {
        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $tmpResumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $tmpResumeTxt2 = $functionObj->replaceChar16($tmpResumeTxt);
        return;
    }

    //学历  degreeCode
    function getDegree() {
        if ($this->trySpecial('degree')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));
        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("学历", "学历情况", "最高学历", "文化程度", "教育情况", "教育程度");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen($doTxtArr[$j]) <= 20) {
                    $resumeInfo['degree'] = $doTxtArr[$j];
                    $resumeInfo['degree_p'] = $j;
                }
                return;
            }
        }

        for ($i = 0; $i < $num; $i++) {
            if (mb_strlen($doTxtArr[$i]) > 100) {
                break;
            }
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $exceptPreg = '/学历(.*)?/';
            preg_match($exceptPreg, $tmpStr, $matchesResult);

            if (isset($matchesResult[1]) && $matchesResult[1] != "" && mb_strlen($matchesResult[1]) < 4) {
                $resumeInfo['degree'] = $matchesResult[1];
                $resumeInfo['degree_p'] = $i;
                return;
            }
        }

        for ($i = 0; $i < $num; $i++) {
            if (mb_strlen($doTxtArr[$i]) > 100) {
                break;
            }
            $tmpStr = $doTxtArr[$i];
            $dictDegreeArr = array(
                "博士后" => 9,
                "博士" => 9,
                "MBA" => 8,
                "EMBA" => 8,
                "硕士" => 7,
                "本科" => 6,
                "大专" => 5,
                "中专" => 4,
                "中技" => 3,
                "中技" => 3,
                "高中" => 2,
                "中学" => 1,
                "初中" => 1,
                "初中以下" => 1,
                "初中及以下" => 1,
                "小学" => 1
            );
            foreach ($dictDegreeArr as $key => $value) {
                if (str_replace(array($value . " ", " " . $value), '', $tmpStr) !== $tmpStr) {
                    $resumeInfo['degree'] = $value;
                    $resumeInfo['degree_p'] = $i;
                    return;
                }
            }
        }

        for ($i = 0; $i < $num; $i++) {
            if (mb_strlen($doTxtArr[$i]) > 100) {
                break;
            }
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $exceptPreg = '/学历(.*)?/';
            preg_match($exceptPreg, $tmpStr, $matchesResult);

            foreach ($dictDegreeArr as $key => $value) {
                if (str_replace(array($value . " ", " " . $value), '', $tmpStr) !== $tmpStr) {
                    $resumeInfo['degree'] = $value;
                    $resumeInfo['degree_p'] = $i;
                    return;
                }
            }
        }

//(?:职位：|职位\s+)(.+?)(?=\s)
        return;
    }

    //专业  majorCode
    function getMajor() {
        if ($this->trySpecial('major')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));


        //排除掉专业技能
        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("专业", "专业方向", "专业领域");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen($doTxtArr[$j]) >= 2 && mb_strlen($doTxtArr[$j]) <= 20) {
                    $resumeInfo['major'] = $doTxtArr[$j];
                    $resumeInfo['major_p'] = $j;
                }
                return;
            }
        }

        for ($i = 0; $i < $num; $i++) {
            $tmpStr = str_replace(array("：", ":"), ':', $doTxtArr[$i]);
            //$exceptPreg = '/(?:(?:专业)(?<!技能|领域|工作)\s*)(S*)(?:\b|\s)/u';
            $exceptPreg = '/(?:(?:专业)\:\s*)(.*)(?:\b|\s)/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);

            if (isset($matchesResult[1]) && $matchesResult[1] != "" && mb_strlen($matchesResult[1]) < 5000) {
                $resumeInfo['major'] = $matchesResult[1];
                $resumeInfo['major_p'] = $i;
                //return;
            }
        }
        return;
    }

    //行业  industryCode
    function getIndustry() {
        if ($this->trySpecial('industry')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("行业", "行业领域", "期望行业", "期望从事行业");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen(trim(trim($doTxtArr[$j], '|'))) <= 200) {
                    $resumeInfo['industry'] = trim(trim($doTxtArr[$j], '|'));
                    $resumeInfo['industry_p'] = $j;
                }
                return;
            }
        }
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = str_replace(array("：", ":"), '', $doTxtArr[$i]);
            $exceptPreg = '/(?:(?:行\s*业|行业领域|期望行业|期望从事行业)\s*)(\S*)(?:\b|\s)/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);

            if (isset($matchesResult[1]) && $matchesResult[1] != "" && mb_strlen(trim(trim($matchesResult[1], '|'))) < 800) {
                $resumeInfo['industry'] = trim(trim($matchesResult[1], '|'));
                $resumeInfo['industry_p'] = $i;
                return;
            }
        }
        return;
    }

    //职业  careerCode
    function getCareer() {
        if ($this->trySpecial('career')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("职业", "期望职业", "期望从事职业");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen($doTxtArr[$j]) <= 20) {
                    $resumeInfo['career'] = $doTxtArr[$j];
                    $resumeInfo['career_p'] = $j;
                }
                return;
            }
        }
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $doTxtArr[$i];
            $exceptPreg = '/(?:(?:职业|期望职业|期望从事职业)\s*)(.+)(?:\b|\s)/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);

            if (isset($matchesResult[1]) && $matchesResult[1] != "" && mb_strlen($matchesResult[1]) < 80) {
                $resumeInfo['career'] = trim(trim($matchesResult[1]), '|');
                $resumeInfo['career_p'] = $i;
                return;
            }
        }
        return;
    }

    //职位  positionCode
    function getPosition() {
        if ($this->trySpecial('position')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("期望职位", "期望从事职业", "期望从事职务", "目标职位", "求职意向", "职位", "头衔", "职称");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen($doTxtArr[$j]) <= 200) {
                    $resumeInfo['position'] = $doTxtArr[$j];
                    $resumeInfo['position_p'] = $j;
                }
                return;
            }
        }
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $doTxtArr[$i];

            $exceptPreg = '/(?:(?:期望职位|期望从事职业|期望从事职务|目标职位|求职意向|职位|头衔|职称)\s*)(\S+)(?:\b|\s)/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);

            if (isset($matchesResult[1]) && $matchesResult[1] != "" && mb_strlen($matchesResult[1]) < 100) {
                $resumeInfo['position'] = $functionObj->filterStr($matchesResult[1]);
                $resumeInfo['position_p'] = $i;
                return;
            }
        }
        return;
    }

    //学校  schoolCode
    function getSchool() {
        if ($this->trySpecial('school')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("毕业学校", "毕业院校", "学校", "院校");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                if (mb_strlen($doTxtArr[$j]) <= 200) {
                    $resumeInfo['school'] = $doTxtArr[$j];
                    $resumeInfo['school_p'] = $j;
                }
                return;
            }
        }
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $doTxtArr[$i];

            $exceptPreg = '/(?:(?:毕业学校|毕业院校|学校|院校)\s*)(\S+)(?:\b|\s)/u';
            preg_match($exceptPreg, $tmpStr, $matchesResult);

            if (isset($matchesResult[1]) && $matchesResult[1] != "" && mb_strlen($matchesResult[1]) < 100) {
                $resumeInfo['school'] = $functionObj->filterStr($matchesResult[1]);
                $resumeInfo['school_p'] = $i;
                return;
            }
        }
        return;
    }


    //勿推企业
    function getNoFocus() {
        if ($this->trySpecial('nofocuse')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            $tagArr = array("勿推企业", "勿推公司", "屏蔽企业", "屏蔽公司", "勿投企业", "勿投公司", "禁投企业", "禁投公司");
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $j = $i + 1;
                if (in_array($doTxtArr[$j], array(':', '：'))) {
                    $j = $j + 1;
                }
                for ($m = $j; $m < $j + 6; $m++) {
                    if (mb_strlen($doTxtArr[$j]) > 500) {
                        break;
                    }
                    if (strpos($doTxtArr[$m], "公司") > 1
                        || strpos($doTxtArr[$m], "企业") > 1
                        || strpos($doTxtArr[$m], "集团") > 1
                        || strpos($doTxtArr[$m], "国际") > 1) {
                        $resumeInfo['nofocuse'] = $doTxtArr[$m];
                        $resumeInfo['nofocuse_p'] = $m;
                        return;
                    }
                }
                return;
            }
        }
        return;
    }

    //婚姻状况  marriedCode
    function getMarried() {
        if ($this->trySpecial('married')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $tagArr = array("已婚", "未婚", "单身", "离异");
        $num = count($doTxtArr);
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $resumeInfo['married'] = $doTxtArr[$i];
                $resumeInfo['married_p'] = $i;
                return;
            }
        }
        if (!isset($resumeInfo['married']) || $resumeInfo['married'] == "") {
            for ($i = 0; $i < $num; $i++) {
                $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
                foreach ($tagArr as $key => $value) {
                    if (strpos($tmpStr, $value)) {
                        $resumeInfo['married'] = $value;
                        $resumeInfo['married_p'] = $i;
                        return;
                    }
                }
            }
        }

        return;
    }

    //政治面貌
    function getPolitic() {
        if ($this->trySpecial('politic')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $resumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $doTxtArr = $functionObj->spiltToArry($resumeTxt, chr(16));

        $num = count($doTxtArr);
        $tagArr = array("党员", "团员", "无党派", "群众", "普通公民");
        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            if (in_array(strtolower($tmpStr), $tagArr)) {
                $resumeInfo['politic'] = $doTxtArr[$i];
                $resumeInfo['politic_p'] = $i;
                return;
            }
        }

        for ($i = 0; $i < $num; $i++) {
            $tmpStr = $functionObj->filterStr($doTxtArr[$i]);
            foreach ($tagArr as $key => $value) {
                if (strpos($tmpStr, $value)) {
                    $resumeInfo['politic'] = $value;
                    $resumeInfo['politic_p'] = $i;
                    return;
                }
            }
        }
        return;
    }

    //全职/兼职
    function getJobTerm() {
        if ($this->trySpecial('jobterm')) return;
    }

    //求职状态
    function getCurrentSituation() {
        if ($this->trySpecial('current_situation')) return;
    }

    //到岗时间
    function getEntryTime() {
        if ($this->trySpecial('entrytime')) return;
    }

    //工作经验
    function getWorkInfo() {
        if ($this->trySpecial('workinfo')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $tmpResumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $tmpResumeTxt2 = $functionObj->replaceChar16($tmpResumeTxt);

        return;
    }

    //项目经验
    function getProjectInfo() {
        if ($this->trySpecial('projectinfo')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $tmpResumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $tmpResumeTxt2 = $functionObj->replaceChar16($tmpResumeTxt);

        return;
    }

    //教育经历
    function getEducationInfo() {
        if ($this->trySpecial('educationinfo')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $tmpResumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $tmpResumeTxt2 = $functionObj->replaceChar16($tmpResumeTxt);


        return;
    }

    //语言能力\技能特长
    function getSkillInfo() {
        if ($this->trySpecial('skillinfo')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $tmpResumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $tmpResumeTxt2 = $functionObj->replaceChar16($tmpResumeTxt);

        return;
    }

    //获奖情况
    function getAwardInfo() {
        if ($this->trySpecial('awardinfo')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $tmpResumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $tmpResumeTxt2 = $functionObj->replaceChar16($tmpResumeTxt);

        return;
    }

    //自我评价
    function getCommentInfo() {
        if ($this->trySpecial('commentinfo')) return;

        $resumeTxtArr = &$this->resume;
        $readFile = &$this->readFile;
        $resumeInfo = &$this->resumeInfo;
        $functionObj = &$this->func;

        $tmpResumeTxt = $functionObj->aloneChar16($resumeTxtArr['resumeAtom']);
        $tmpResumeTxt2 = $functionObj->replaceChar16($tmpResumeTxt);

        return;
    }

    //附加信息
    function getOtherInfo() {
        if ($this->trySpecial('otherinfo')) return;


    }

    //头像
    function getAvatar() {
        if ($this->trySpecial('avatar')) return;
    }

    //尝试通过特定简历类型获取值并直接存入对应键，失败返回FALSE。
    function trySpecial($tagName) {
        if (!$this->parsingSpecial) {
            return FALSE;
        }
        $getters = $this->parsingSpecial->get;
        if (!isset($getters[$tagName]) || !is_callable($getters[$tagName])) {
            if ($this->debugSpecial) var_dump('【trySpecial [' . $tagName . '] fail: getter not found】');
            return FALSE;
        }

        $this->resumeInfo[$tagName] = $getters[$tagName]();
        if ($this->debugSpecial) var_dump('trySpecial [' . $tagName . '] success: ' . (is_array($this->resumeInfo[$tagName]) ? print_r($this->resumeInfo[$tagName], TRUE) : $this->resumeInfo[$tagName]));
        return TRUE;
    }

    //$tagType: 项目名称出现位置 0 - 必须出现在前方，1 - 必须出现前后皆可，2 - 出现在前方或不出现
    function getTag($targetName, $tagName, $mainFormat, $tagType = 0, $requireTagBoundery = FALSE, $tagCaseSensitive = FALSE) {
        $regex = $this->composeRegex($tagName, $mainFormat, $tagType, $requireTagBoundery, $tagCaseSensitive);
        preg_match($regex, $this->resumeText, $matchesResult, PREG_OFFSET_CAPTURE);
        //var_dump(htmlspecialchars($regex));
        if (is_array($matchesResult) && isset($matchesResult['result']) && is_array($matchesResult['result'])) {
            $this->resumeInfo[$targetName] = $matchesResult['result'][0];
            $this->resumeInfo[$targetName . '_p'] = $matchesResult['result'][1];
            return TRUE;
        }
        return FALSE;
    }

    //$tagType: 项目名称出现位置 0 - 必须出现在前方，1 - 必须出现前后皆可，2 - 出现在前方或不出现
    function composeRegex($tagName, $mainFormat, $tagType = 0, $requireTagBoundery = FALSE, $tagCaseSensitive = FALSE) {
        if (is_string($tagName)) $tagName = array($tagName);
        if (!is_array($tagName) || !count($tagName)) return $mainFormat;
        $tagNamePart = implode('|', array_map(function ($item) {    //较短的项目名称容许较多空格插入
            switch (mb_strlen($item)) {
                case 2:
                    $glue = '\s{0,6}';
                    break;
                case 3:
                    $glue = '\s{0,3}';
                    break;
                case 4:
                    $glue = '\s{0,2}';
                    break;
                case 5:
                    $glue = '\s?';
                    break;
                default:
                    $glue = '';
            }
            if ($glue) {
                $chars = preg_split('//u', $item, -1, PREG_SPLIT_NO_EMPTY);
                return implode($glue, $chars);
            }
            return $item;
        }, $tagName));
        $tagNamePart = '(?:' . ($tagCaseSensitive ? '' : '(?i)') . $tagNamePart . ')';
        $tagBoundery = $requireTagBoundery ? '\b' : '';
        $resultPrefix = mb_strpos($mainFormat, '(?<result>') !== FALSE ? ':' : '<result>';
        switch ($tagType) {
            case 1:
                return '/(?:(?<tag>' . $tagBoundery . $tagNamePart . '\s*[\pP\pS]*\s*' . $tagBoundery . ')|\b|\s)(?' . $resultPrefix . $mainFormat . ')(?(tag)(?=\b|\s)|\s{' . ($requireTagBoundery ? '1' : '0') . ',3}' . $tagNamePart . ')/mu';
            case 2:
                return '/(?:' . $tagBoundery . $tagNamePart . '\s*[\pP\pS]*\s*' . $tagBoundery . '|\b|\s)(?' . $resultPrefix . $mainFormat . ')(?=\b|\s)/mu';
            case 0:
            default:
                return '/(?:' . $tagBoundery . $tagNamePart . '\s*[\pP\pS]*\s*' . $tagBoundery . ')(?' . $resultPrefix . $mainFormat . ')(?=\b|\s)/mu';
        }
    }

    function getProfile() {
        static $delimiter = ' | ';
        $resumeInfo = &$this->resumeInfo;
        $profile = '';
        if (!empty($resumeInfo['commentinfo']) && is_string($resumeInfo['commentinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【自我评价】' . PHP_EOL . $resumeInfo['commentinfo'];
        }
        //var_dump($resumeInfo);
        if (is_array($resumeInfo['workinfo']) && count($resumeInfo['workinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【工作经历】';
            foreach ($resumeInfo['workinfo'] as $item) {
                $profile .= PHP_EOL . implode($delimiter, array_filter([$item['time'], $item['company'], $item['duty'], $item['salary']])) . PHP_EOL . $item['comment'];
            }
        }
        if (is_array($resumeInfo['projectinfo']) && count($resumeInfo['projectinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【项目经历】';
            foreach ($resumeInfo['projectinfo'] as $item) {
                $profile .= PHP_EOL . implode($delimiter, array_filter([$item['time'], $item['project'], $item['company'], $item['duty']])) . PHP_EOL . $item['comment'];
            }
        }
        if (is_array($resumeInfo['educationinfo']) && count($resumeInfo['educationinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【教育经历】';
            foreach ($resumeInfo['educationinfo'] as $item) {
                $profile .= PHP_EOL . implode($delimiter, array_filter([$item['time'], $item['school'], $item['major'], $item['degree']]));
                if (!empty($item['comment'])) $profile .= PHP_EOL . $item['comment'];
            }
        }
        if (!empty($resumeInfo['skillinfo']) && is_string($resumeInfo['skillinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【技能特长】' . PHP_EOL . $resumeInfo['skillinfo'];
        }
        if (!empty($resumeInfo['awardinfo']) && is_string($resumeInfo['awardinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【获奖情况】' . PHP_EOL . $resumeInfo['awardinfo'];
        }
        if (!empty($resumeInfo['otherinfo']) && is_string($resumeInfo['otherinfo'])) {
            $profile .= PHP_EOL . PHP_EOL . '【附加信息】' . PHP_EOL . $resumeInfo['otherinfo'];
        }
        $resumeInfo['profile'] = trim($profile);
        return $resumeInfo['profile'];
    }
}